<?php

namespace Yolo\Components\Cache;

use Yolo\Di\Annotations\Singleton;

#[Singleton]
class MemoryCache implements CacheInterface
{
    private array $cache = [];

    /**
     * Get a value from the cache.
     * @param string $key
     * @return mixed
     */
    public function get(string $key): mixed
    {
        if (!$this->exists($key)) {
            return null;
        }

        return $this->cache[$key]['data'];
    }

    /**
     * Set a value in the cache.
     * @param string $key
     * @param mixed $value
     * @param int $expireIn
     * @return void
     */
    public function set(string $key, mixed $value, int $expireIn = 3600): void
    {
        $this->cache[$key] = [
            'data' => $value,
            'expireAt' => time() + $expireIn
        ];
    }

    /**
     * Delete a value from the cache.
     * @param string $key
     * @return int|bool
     */
    public function delete(string $key): int|false
    {
        if (!$this->exists($key)) {
            return 0;
        }

        unset($this->cache[$key]);
        return 1;
    }

    /**
     * Clear the cache.
     * @return void
     */
    public function clear(): void
    {
        $this->cache = [];
    }

    /**
     * Check if a key exists in the cache.
     * @param string $key
     * @return bool
     */
    public function exists(string $key): bool
    {
        if (!isset($this->cache[$key])) {
            return false;
        }

        if ($this->cache[$key]['expireAt'] > time()) {
            return true;
        }

        // Remove expired key
        unset($this->cache[$key]);

        return false;
    }
}
